<template>
  <div class="map_outer"></div>
</template>

<script>
export default {
  name: "map_point",
  props: ['point_list', 'content_html'],
  emits: ['create','click'],
  data(){
    return {
      marker_cluster: '',
      map_status: false,
    }
  },
  methods: {
    onclick(e){
      let data = e.geometry;
      let content = this.content_html(data);
      if (data.info_window instanceof TMap.InfoWindow){
        data.info_window.open()
      }else {
        data.info_window = new TMap.InfoWindow({
          map: e.target.map,
          position: data.position,
          content: content,
          offset: { x: 0, y: -32 }
        });
      }
    },
    //设置标点
    set_geometries(){
      if (!this.map_status) return;
      this.marker_cluster.setGeometries(this.latlng_list);
    },
    init_map(){
      let app = this, map, marker = null, dom = this.$el;
      map = new TMap.Map(dom, {
        zoom: 4.5,
        center: new TMap.LatLng(35.76952494967395, 107.03757037136839),
        draggableCursor: 'default',
        draggingCursor: 'default',
      });
      app.marker_cluster = new TMap.MarkerCluster({
        id: 'cluster'+(new Date()).getTime(), //图层id
        map: map,       //设置点聚合显示在哪个map对象中（创建map的段落省略）
        enableDefaultStyle: false,   //使用默认样式
        minimumClusterSize: 2,  //最小聚合点数：2个
        geometries: app.latlng_list,
        zoomOnClick: true,  //点击聚合数字放大展开
        gridSize: 60,       //聚合算法的可聚合距离，即距离小于该值的点会聚合至一起，默认为60，以像素为单位
        averageCenter: false, //每个聚和簇的中心是否应该是聚类中所有标记的平均值
        maxZoom: 16 //采用聚合策略的最大缩放级别，若地图缩放级别大于该值，则不进行聚合，标点将全部被展开
      });
      // 以下代码为基于DOMOverlay实现聚合点气泡
      function ClusterBubble(options) {
        TMap.DOMOverlay.call(this, options);
      }
      ClusterBubble.prototype = new TMap.DOMOverlay();
      ClusterBubble.prototype.onInit = function (options) {
        this.content = options.content;
        this.position = options.position;
      };
      ClusterBubble.prototype.onDestroy = function() {
        this.dom.removeEventListener('click', this.onClick);
        this.removeAllListeners();
      };
      ClusterBubble.prototype.onClick = function() {
        this.emit('click');
      };
      // 创建气泡DOM元素
      ClusterBubble.prototype.createDOM = function () {
        var dom = document.createElement('div');
        dom.classList.add('clusterBubble');
        dom.innerText = this.content;
        dom.style.cssText = [
          'width: ' + (20 + parseInt(this.content) * 2) + 'px;',
          'height: ' + (20 + parseInt(this.content) * 2) + 'px;',
          'line-height: ' + (20 + parseInt(this.content) * 2) + 'px;',
          'font-size: 16px;',
          'border-radius: 50%;',
          'color: #fff;',
          'font-weight: 500;',
          'text-align: center;',
          'opacity: 0.88;',
          'background-image: linear-gradient(139deg, #4294FF 0%, #295BFF 100%);',
          'box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.20);',
          'cursor: default;',
          'position: absolute;',
          'top: 0px;',
          'left: 0px;',
        ].join(' ');
        // 监听点击事件，实现zoomOnClick
        this.onClick = this.onClick.bind(this);
        // pc端注册click事件，移动端注册touchend事件
        dom.addEventListener('click', this.onClick);
        return dom;
      };
      ClusterBubble.prototype.updateDOM = function () {
        if (!this.map) return;
        // 经纬度坐标转容器像素坐标
        let pixel = this.map.projectToContainer(this.position);

        // 使文本框中心点对齐经纬度坐标点
        let left = pixel.getX() - this.dom.clientWidth / 2 + 'px';
        let top = pixel.getY() - this.dom.clientHeight / 2 + 'px';
        this.dom.style.transform = `translate(${left}, ${top})`;

        this.emit('dom_updated');
      };

      var clusterBubbleList = [];
      var markerGeometries = [];

      // 监听聚合簇变化
      app.marker_cluster.on('cluster_changed', function (e) {
        // 销毁旧聚合簇生成的覆盖物
        if (clusterBubbleList.length) {
          clusterBubbleList.forEach(function (item) {
            item.destroy();
          })
          clusterBubbleList = [];
        }
        markerGeometries = [];

        // 根据新的聚合簇数组生成新的覆盖物和点标记图层
        var clusters = app.marker_cluster.getClusters();
        clusters.forEach(function (item) {
          if (item.geometries.length > 1) {
            let clusterBubble = new ClusterBubble({
              map: map,
              position: item.center,
              content: item.geometries.length,
            });
            clusterBubble.on('click', () => {
              map.fitBounds(item.bounds);
            });
            clusterBubbleList.push(clusterBubble);
          } else {
            markerGeometries.push(item.geometries[0]);
          }
        });

        if (marker) {
          marker.setGeometries(markerGeometries);
          // marker.destroy();
        }else {
          marker = new TMap.MultiMarker({
            map: map,
            geometries: markerGeometries
          });
          marker.on('click', function (e){
            app.onclick(e);
          })
        }
      });
      this.map_status = true;
    },
  },
  watch: {
    'point_list'(v){
      this.set_geometries();
    }
  },
  computed: {
    latlng_list(){
      if (typeof(TMap) == 'undefined') return [];
      let list = this.point_list || [];
      let latlng_list = [];
      s94Mjs.each(list, function (v){
        if (v.position instanceof TMap.LatLng){
          latlng_list.push(v);
        }else {
          let arr = v.position;
          if (typeof(v.position) == 'string'){
            arr = v.position.split(',');
          }
          if (arr instanceof Array && arr.length==2){
            v.position = new TMap.LatLng(arr[1], arr[0]);
            latlng_list.push(v);
          }
        }
      })
      return latlng_list;
    },
  },
  mounted(){
    //渲染完成执行
    let app = this;
    let map_ready = new Promise(function (next){setTimeout(next, 500)})
    s94Mjs.loadJs('https://map.qq.com/api/gljs?v=1.exp&key=LQ6BZ-4O6RN-7FZFF-S3PRB-EL5U3-OZBH3&libraries=service', ()=>{
      map_ready.then(()=>{ app.init_map(); })
    })
  }
}
</script>

<style scoped>

</style>